//
// Created by Administrator on 2021/3/1.
//

#include "gtk_ui.h"
#include <stdlib.h>
#include <gtk/gtk.h>

#define input_0 "0"
#define input_1 "1"
#define input_2 "2"
#define input_3 "3"
#define input_4 "4"
#define input_5 "5"
#define input_6 "6"
#define input_7 "7"
#define input_8 "8"
#define input_9 "9"
#define input_plus "+"
#define input_minus "-"
#define input_multiply "*"
#define input_divide "/"
#define input_equal "="
#define input_clear "C"
#define input_sign "S"
#define input_percent "%"
#define input_point "."

#define BIND_BUTTON(builder, input_value) \
{GtkButton* button_input_##input_value = (GtkButton *) gtk_builder_get_object(builder, "input_"#input_value); \
g_signal_connect(button_input_##input_value,"clicked",G_CALLBACK(OnInputButtonClicked),input_##input_value);}

UIContext *ui_context_gtk;

static void DisplayTextWithLabel(char *text){
  gtk_label_set_text(ui_context_gtk->text_displayer, text);
}

static void OnInputButtonClicked(void *widget, void *data){
  HandleInput(ui_context_gtk->context, ((char *) data)[0]);
}

static void GTKUIMain(int argc, char *argv[]){
  gtk_init(&argc, &argv);

  GError *error = NULL;
  GtkCssProvider *css_provider = gtk_css_provider_new();
  if (gtk_css_provider_load_from_path(css_provider, "src/calculator.css", &error) == 0) {
    g_printerr("Error loading css file: %s\n", error->message);
    g_clear_error(&error);
    return;
  }

  GtkBuilder *builder = gtk_builder_new();
  if (gtk_builder_add_from_file(builder, "src/calculator.ui", &error) == 0) {
    g_printerr("Error loading builder file: %s\n", error->message);
    g_clear_error(&error);
    return;
  }

  GtkWindow *window = (GtkWindow *) gtk_builder_get_object(builder, "window");
  gtk_style_context_add_provider_for_screen(gtk_window_get_screen(window), (GtkStyleProvider *) css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER);
  g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);

  ui_context_gtk->text_displayer = (GtkLabel *) gtk_builder_get_object(builder, "display");

  BIND_BUTTON(builder,0);
  BIND_BUTTON(builder,1);
  BIND_BUTTON(builder,2);
  BIND_BUTTON(builder,3);
  BIND_BUTTON(builder,4);
  BIND_BUTTON(builder,5);
  BIND_BUTTON(builder,6);
  BIND_BUTTON(builder,7);
  BIND_BUTTON(builder,8);
  BIND_BUTTON(builder,9);
  BIND_BUTTON(builder,plus);
  BIND_BUTTON(builder,minus);
  BIND_BUTTON(builder,multiply);
  BIND_BUTTON(builder,divide);
  BIND_BUTTON(builder,equal);
  BIND_BUTTON(builder,clear);
  BIND_BUTTON(builder,sign);
  BIND_BUTTON(builder,percent);
  BIND_BUTTON(builder,point);

  HandleInput(ui_context_gtk->context, '0');

  gtk_main();

  g_object_unref(builder);
  gtk_style_context_remove_provider_for_screen(gtk_window_get_screen(window), (GtkStyleProvider *) css_provider);
  g_object_unref(css_provider);
}

static void InitGTKUI(){
  ui_context_gtk = malloc(sizeof(UIContext));
  ui_context_gtk->context = CreateCalcContext();
  ui_context_gtk->context->display_text = DisplayTextWithLabel;
}

static void DestroyGTKUI(){
  DestroyCalcContext(&ui_context_gtk->context);
  free(ui_context_gtk);
  ui_context_gtk = NULL;
}

int RunGTKUI(int argc, char *argv[]){
  InitGTKUI();

  GTKUIMain(argc,argv);

  DestroyGTKUI();
}
